package com.ruoyi.framework.websocket;
import cn.hutool.core.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.websocket.Session;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @Author wy
 * @Description 当前websocket用户工具
 * @Date 2023/11/27 14:27
 * @Version 1.0
 */
public class WebSocketUsers {

    /**
     * WebSocketUsers 日志控制器
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketUsers.class);

    /**
     * 存储当前要使用websocket用户集  <SessionId,Session></SessionId,Session>
     */
    private static Map<String, Session> USERS = new ConcurrentHashMap<String, Session>();

    /**
     * 存储 websocket sessionId对应的名称  <SessionId,UserName></SessionId,UserName>
     */
    private static Map<String,String> USERNAMES=new ConcurrentHashMap<String,String>();

    /**
     * 添加存储用户
     * @param key  sessionid
     * @param userName  用户名
     * @param session session对象
     */
    public static void put(String key,String userName, Session session) {
        //存储session对象
        USERS.put(key, session);
        //存名称
        USERNAMES.put(key,userName);
    }

    /**
     * 移除用户
     *
     * @param session 用户信息
     *
     * @return 移除结果
     */
    public static boolean remove(Session session) {
        String key = null;
        boolean flag = USERS.containsValue(session);
        if (flag) {
            Set<Map.Entry<String, Session>> entries = USERS.entrySet();
            for (Map.Entry<String, Session> entry : entries)
            {
                Session value = entry.getValue();
                if (value.equals(session)) {
                    key = entry.getKey();
                    break;
                }
            }
        }
        else {
            return true;
        }
        return remove(key);
    }

    /**
     * 移出用户
     *
     * @param key 键
     */
    public static boolean remove(String key)
    {
        LOGGER.info("\n 正在移出用户 - {}", key);
        //移出Session
        Session remove = USERS.remove(key);
        //移出用户名
        USERNAMES.remove(key);

        if (remove != null) {
            boolean containsValue = USERS.containsValue(remove);
            LOGGER.info("\n 移出结果 - {}", containsValue ? "失败" : "成功");
            return containsValue;
        }
        else
        {
            return true;
        }
    }

    /**
     * 获取在线用户列表
     *
     * @return 返回用户集合
     */
    public static Map<String, Session> getUserSession()
    {
        return USERS;
    }

    /**
     * 获取在线用户名称
     * @return
     */
    public static List<String> getUserNames(){
        return USERNAMES.values().stream().collect(Collectors.toList());
    }

    /**
     * 向所有用户，群发消息文本消息
     *
     * @param message 消息内容
     */
    public static void sendMessageToUsersByText(String message)
    {
        Collection<Session> values = USERS.values();
        for (Session value : values)
        {
            sendMessageToUserByText(value, message);
        }
    }

    /**
     * 发送文本消息
     *
     * @param session 自己的用户名
     * @param message 消息内容
     */
    public static void sendMessageToUserByText(Session session, String message) {
        if (session != null) {
            try
            {
                session.getBasicRemote().sendText(message);
            }
            catch (IOException e)
            {
                LOGGER.error("\n[发送消息异常]", e);
            }
        }
        else
        {
            LOGGER.info("\n[你已离线]");
        }
    }

    /**
     * 向某一个用户发消息
     * @param userName
     * @param message
     */
    public static void sendMessageToUserByText(String userName, String message){
        Session session = getSessionByUserName(userName);
       if(session==null){
           LOGGER.error("\n[向]"+userName+"发送消息失败，原因该用户不存在");
       }else{
           sendMessageToUserByText(session,message);
       }

    }

    /**
     * 获取session对象
     * @param userName
     * @return
     */
   public static  Session  getSessionByUserName(String userName){
       Set<Map.Entry<String, String>> entries = USERNAMES.entrySet();
       String sessionId=null;
       for (Map.Entry<String, String> entry : entries) {
          String value = entry.getValue();
           if (value.equals(userName)) {
               sessionId = entry.getKey();
               break;
           }
       }
       if(StrUtil.isNotBlank(sessionId)){
           return USERS.get(sessionId);
       }
       return null;
   }

}
